import { DEBUG } from 'cc/env';

import EventExt from './EventExt';

/** 游戏音效设置变动 */
export const EVENT_KEY_SOUND_SETTING: string = "event_key_sound_setting";
/** 音效状态二进制枚举 */
export enum TAudioStatus {
    /** 静音总开关 */
    Mute = 1 << 0,
    /** 背景音乐开关 */
    BGM = 1 << 1,
    /** 游戏音效开关 */
    Sound = 1 << 2,
    /** 任务语音开关 */
    Voice = 1 << 3
}
/** 设置音效开关事件 -- 可传递复合状态 */
export interface IAudioSet {
    /** 类型 */
    type: TAudioStatus;
    /** 开关 */
    status: boolean;
}

export default class AudioSetting {

    // 单例
    static getIns(): AudioSetting {
        if (!this._ins)
            this._ins = new AudioSetting();
        return this._ins;
    }
    private static _ins: AudioSetting = null;
    private constructor() { }


    /** 静音总开关 */
    static get mute(): boolean {
        return AudioSetting.getStatus(TAudioStatus.Mute);
    }
    static set mute(b: boolean) {
        AudioSetting.setStatus(TAudioStatus.Mute, b);
    }

    /** BGM */
    static get BGM(): boolean {
        return AudioSetting.getStatus(TAudioStatus.BGM) && !this.mute;
    }
    static set BGM(b: boolean) {
        AudioSetting.setStatus(TAudioStatus.BGM, b);
    }

    /** 游戏音效 */
    static get sound(): boolean {
        return AudioSetting.getStatus(TAudioStatus.Sound) && !this.mute;
    }
    static set sound(b: boolean) {
        AudioSetting.setStatus(TAudioStatus.Sound, b);
    }
    
    /** 人物语音 */
    static get voice(): boolean {
        return AudioSetting.getStatus(TAudioStatus.Voice) && !this.mute;
    }
    static set voice(b: boolean) {
        AudioSetting.setStatus(TAudioStatus.Voice, b);
    }


    /** 获取指定状态 */
    static getStatus(type: TAudioStatus): boolean {
        return (this.getIns().audioStatus & type) != 0;
    }

    /** 设置指定状态 */
    static setStatus(type: TAudioStatus, status: boolean) {
        this.getIns().audioStatus = status ? (this.getIns().audioStatus | type) : (this.getIns().audioStatus & ~type);
        DEBUG && console.log("[AudioSetting] 修改 audioStatus:", Number(globalThis._audioStatus).toString(2));
        EventExt.emit(EVENT_KEY_SOUND_SETTING, { type, status } as IAudioSet);
    }


    /** 全局音效设置状态 -- 默认全部开启 */
    private get audioStatus(): number {
        if (globalThis._audioStatus == undefined) {
            const yyset = globalThis.yycore?.games?.setting;
            if (yyset) {
                globalThis._audioStatus = 0;
                if (yyset.isMute)
                    globalThis._audioStatus = globalThis._audioStatus | TAudioStatus.Mute;
                if (yyset.isMusicEnable)
                    globalThis._audioStatus = globalThis._audioStatus | TAudioStatus.BGM;
                if (yyset.isEffectEnable)
                    globalThis._audioStatus = globalThis._audioStatus | TAudioStatus.Sound;
                if (yyset.isVoiceEnable)
                    globalThis._audioStatus = globalThis._audioStatus | TAudioStatus.Voice;
            }
            else {
                /** 默认关闭静音，开启全部音效 */
                globalThis._audioStatus = TAudioStatus.BGM | TAudioStatus.Sound | TAudioStatus.Voice;
            }
            DEBUG && console.log("[AudioSetting] 初始化 audioStatus:", Number(globalThis._audioStatus).toString(2));
        }
        return globalThis._audioStatus;
    }
    private set audioStatus(n: number) {
        globalThis._audioStatus = n;
    }
    
}